import { IPSAppDataEntity, IPSAppViewRef } from '@ibizstudio/runtime';
import { ViewTool, Util, LogUtil, StringUtil } from '@ibizstudio/runtime';
import { isFunc } from 'qx-util';
import { appPopup } from '../../utils';
import { AppGlobalService } from './app-global-action-service';
/**
 * 应用功能服务
 *
 * @memberof AppFuncService
 */
export class AppFuncService {
  /**
   * 单例变量声明
   *
   * @memberof AppFuncService
   */
  private static appFuncService: AppFuncService;

  /**
   * 构造 AppFuncService 对象
   *
   * @memberof AppViewLogicService
   */
  constructor() {}

  /**
   * vue对象
   *
   * @memberof AppFuncService
   */
  v!: any;

  /**
   * 初始化
   *
   * @memberof AppFuncService
   */
  init(vueInstance: any): void {
    this.v = vueInstance;
  }

  /**
   * 获取 AppFuncService 单例对象
   *
   * @memberof AppFuncService
   */
  static getInstance() {
    if (!this.appFuncService) {
      this.appFuncService = new AppFuncService();
    }
    return this.appFuncService;
  }

  /**
   * 执行应用功能
   *
   * @memberof AppFuncService
   */
  async executeApplication(appFunc: any, context: any) {
    if (!context) {
      context = {};
    }
    if (appFunc) {
      const viewParam: any = {};
      if (isFunc(appFunc.getPSAppView)) {
        const appView = appFunc.getPSAppView();
        if (appView) {
          await appView.fill();
        }
      } else if (appFunc.getPSAppView) {
        await appFunc.getPSAppView.fill();
      }

      if (isFunc(appFunc.getPSNavigateContexts)) {
        const localContext = Util.formatNavParam(appFunc.getPSNavigateContexts() || []);
        Object.assign(context, localContext);
      } else if (appFunc.getPSNavigateContexts) {
        const localContext = Util.formatNavParam(appFunc.getPSNavigateContexts);
        Object.assign(context, localContext);
      }

      if (isFunc(appFunc.getPSNavigateParams)) {
        const localViewParam = Util.formatNavParam(appFunc.getPSNavigateParams() || []);
        Object.assign(viewParam, localViewParam);
      } else if (appFunc.getPSNavigateParams) {
        const localViewParam = Util.formatNavParam(appFunc.getPSNavigateParams);
        Object.assign(viewParam, localViewParam);
      }

      switch (appFunc.appFuncType) {
        case 'APPVIEW':
          const view = isFunc(appFunc.getPSAppView) ? appFunc.getPSAppView() : appFunc.getPSAppView;
          await this.openAppView(view, context, viewParam);
          return;
        case 'OPENHTMLPAGE':
          this.openHtmlPage(appFunc, context, viewParam);
          return;
        case 'PDTAPPFUNC':
          this.openPdAppFunc(appFunc, context, viewParam);
          return;
        case 'JAVASCRIPT':
          this.executeJavaScript(appFunc, context, viewParam);
          return;
        case 'CUSTOM':
          this.custom(appFunc, context, viewParam);
          return;
        case "UIACTION":
            // 暂时获取不到'APP_LOGOUT' 
            if(appFunc.name ===  "登出"){
              AppGlobalService.getInstance().executeGlobalAction('APP_LOGOUT',[])
            }
          return;
        default:
          LogUtil.warn('无该应用功能');
      }
    }
  }

  /**
   * 打开应用视图
   *
   * @memberof AppFuncService
   */
  async openAppView(appView: any, context: any, viewparam: any = {}, ref?: IPSAppViewRef) {
    if (Object.values(appView).length == 0) {
      console.error('未找到应用视图');
      return;
    }
    if (appView.redirectView) {
      this.v.$warning('重定向视图暂不支持应用功能打开', 'openAppView');
    } else {
      if (appView.openViewParam) {
        Object.assign(viewparam, appView.openViewParam);
      }
      const deResParameters: any[] = [];
      const parameters: any[] = [];
      const openMode = ref?.openMode ? ref.openMode : appView.openMode;
      await this.processingParameter(context, appView, deResParameters, parameters, openMode);
      if (openMode && Object.is(openMode, 'INDEXVIEWTAB')) {
        this.openIndexViewTab(context, viewparam, deResParameters, parameters);
      } else if (openMode && Object.is(openMode, 'POPUP')) {
        this.openPopup(context, viewparam, appView);
      } else if (openMode && Object.is(openMode, 'POPUPMODAL')) {
        this.openModal(context, viewparam, appView);
      } else if (openMode && Object.is(openMode, 'POPUPAPP')) {
        this.openApp(context, viewparam, deResParameters, parameters);
      } else if (openMode && Object.is(openMode, 'POPOVER')) {
        this.openPopover(context, viewparam, appView);
      } else if (openMode && openMode.indexOf('DRAWER') != -1) {
        this.openDrawer(context, viewparam, appView);
      } else if (openMode && openMode.indexOf('USER') != -1) {
        this.openUser(context, viewparam, deResParameters, parameters);
      } else {
        this.openIndexViewTab(context, viewparam, deResParameters, parameters);
      }
    }
  }

  /**
   * 整合参数
   *
   * @memberof AppFuncService
   */
  async processingParameter(context: any, appView: any, deResParameters: any[], parameters: any[], openMode: string) {
    let params = [];
    if (appView.getPSAppDataEntity()) {
      let result: IPSAppDataEntity = appView.getPSAppDataEntity();
      await result.fill();
      if (!result) {
        console.error('未找到应用实体');
        return;
      }
      if ((openMode && (openMode == 'INDEXVIEWTAB' || openMode == '')) || !openMode) {
        params = [
          {
            pathName: Util.srfpluralize(result.codeName).toLowerCase(),
            parameterName: result.codeName.toLowerCase(),
          },
          { pathName: 'views', parameterName: appView.getPSDEViewCodeName().toLowerCase() },
        ];
      } else {
        params = [
          {
            pathName: Util.srfpluralize(result.codeName).toLowerCase(),
            parameterName: result.codeName.toLowerCase(),
          },
        ];
      }
    } else {
      params = [{ pathName: 'views', parameterName: appView.name.toLowerCase() }];
    }
    Object.assign(parameters, params);
  }

  /**
   * 顶级分页打开
   *
   * @memberof AppFuncService
   */
  openIndexViewTab(context: any, viewparam: any, deResParameters: any[], parameters: any[]) {
    if (context && context.srfdynainstid) {
      Object.assign(viewparam, { srfdynainstid: context.srfdynainstid });
    }
    const path: string = ViewTool.buildUpRoutePath(this.v.$route, context, deResParameters, parameters, [], viewparam);
    if (Object.is(this.v.$route.fullPath, path)) {
      return;
    }
    this.v.$nextTick(() => {
      this.v.$router.push({ path, query: { viewdata: JSON.stringify(viewparam) } });
    });
  }

  /**
   * 非模式弹出
   *
   * @memberof AppFuncService
   */
  openPopup(context: any, viewparam: any, appView: any) {
    const view = {
      viewname: 'app-view-shell',
      title: this.v.$tl(appView.getCapPSLanguageRes()?.lanResTag, appView.caption),
      height: appView.height,
      width: appView.width,
    };
    if (appView.modelPath) {
      Object.assign(context, { viewpath: appView.modelPath });
    }
    const container = appPopup.openDrawer(view, Util.getViewProps(context, viewparam), {
      viewModelData: appView,
    });
    container.subscribe((result: any) => {
      LogUtil.log(result);
    });
  }

  /**
   * 模态打开
   *
   * @memberof AppFuncService
   */
  openModal(context: any, viewparam: any, appView: any) {
    const view = {
      viewname: 'app-view-shell',
      title: this.v.$tl(appView.getCapPSLanguageRes()?.lanResTag, appView.caption),
      height: appView.height,
      width: appView.width,
    };
    if (appView.modelPath) {
      Object.assign(context, { viewpath: appView.modelPath });
    }
    const appmodal = this.v.$appmodal.openModal(view, Util.deepCopy(context), viewparam);
    appmodal.subscribe((result: any) => {
      LogUtil.log(result);
    });
  }

  /**
   * 独立程序弹出
   *
   * @memberof AppFuncService
   */
  openApp(context: any, viewparam: any, deResParameters: any[], parameters: any[]) {
    if (context && context.srfdynainstid) {
      Object.assign(viewparam, { srfdynainstid: context.srfdynainstid });
    }
    const routePath = ViewTool.buildUpRoutePath(this.v.$route, context, deResParameters, parameters, [], viewparam);
    window.open('./#' + routePath, '_blank');
  }

  /**
   * 气泡打开
   *
   * @memberof AppFuncService
   */
  openPopover(context: any, viewparam: any, appView: any) {
    const view = {
      viewname: 'app-view-shell',
      title: this.v.$tl(appView.getCapPSLanguageRes()?.lanResTag, appView.caption),
      height: appView.height,
      width: appView.width,
      placement: appView.openMode,
    };
    if (appView.modelPath) {
      Object.assign(context, { viewpath: appView.modelPath });
    }
    const appPopover = this.v.$apppopover.openPop({}, view, Util.deepCopy(context), viewparam);
    appPopover.subscribe((result: any) => {
      LogUtil.log(result);
    });
  }

  /**
   * 抽屉打开
   *
   * @memberof AppFuncService
   */
  openDrawer(context: any, viewparam: any, appView: any) {
    const view = {
      viewname: 'app-view-shell',
      title: this.v.$tl(appView.getCapPSLanguageRes()?.lanResTag, appView.caption),
      height: appView.height,
      width: appView.width,
      placement: appView.openMode,
    };
    const appdrawer = this.v.$appdrawer.openDrawer(view, Util.getViewProps(context, viewparam), {
      viewModelData: appView,
    });
    appdrawer.subscribe((result: any) => {
      LogUtil.log(result);
    });
  }

  /**
   * 用户自定义
   *
   * @memberof AppFuncService
   */
  openUser(context: any, viewparam: any, deResParameters: any[], parameters: any[]) {
    LogUtil.log('用户自定义，暂时不实现');
  }

  /**
   * 打开HTML页面
   *
   * @memberof AppFuncService
   */
  openHtmlPage(appFunc: any, context: any, viewparam: any) {
    const url = StringUtil.fillStrData(appFunc.htmlPageUrl, context);
    window.open(url, '_blank');
  }

  /**
   * 预置应用功能
   *
   * @memberof AppFuncService
   */
  openPdAppFunc(appFunc: any, context: any, viewparam: any) {
    this.v.$warning('预置应用功能暂不支持', 'openPdAppFunc');
  }

  /**
   * 执行JS
   *
   * @memberof AppFuncService
   */
  executeJavaScript(appFunc: any, context: any, viewparam: any) {
    this.v.$warning('执行JS暂不支持', 'executeJavaScript');
  }

  /**
   * 自定义
   *
   * @memberof AppFuncService
   */
  custom(appFunc: any, context: any, viewparam: any) {
    this.v.$warning('自定义暂不支持', 'custom');
  }
}
